#![no_main]
#![no_std]
#![feature(panic_info_message)]
#[macro_use]
mod console;
mod lang_items;
mod sbi;

use core::arch::global_asm;
global_asm!(include_str!("entry.asm"));

#[no_mangle]
pub fn rust_main() -> ! {
    clear_bss();
    extern "C" {
        fn stext();
        fn etext();
        fn sdata();
        fn edata();
        fn srodata();
        fn erodata();
        fn sbss();
        fn ebss();
    }
    println!("Hello, world!");
    log!(info, "Hello, world!");
    log!(error, "Hello, world!");
    log!(warn, "Hello, world!");
    log!(debug, "Hello, world!");
    log!(trace, "Hello, world!");
    log!(info, ".text: {:#x} - {:#x}", stext as usize, etext as usize);
    log!(
        info,
        ".rodata: {:#x} - {:#x}",
        srodata as usize,
        erodata as usize
    );
    log!(info, ".data: {:#x} - {:#x}", sdata as usize, edata as usize);
    log!(info, ".bss: {:#x} - {:#x}", sbss as usize, ebss as usize);

    panic!("Shutdown machine!");
}

fn clear_bss() {
    extern "C" {
        fn sbss();
        fn ebss();
    }

    (sbss as usize..ebss as usize).for_each(|b| unsafe { (b as *mut u8).write_volatile(0) });
}
